﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autocentro.Entities;
using Autocentro.Respository;
using Microsoft.Practices.Unity;

namespace Autocentro.BussinesLogic
{    
    public class VentaBL : IVentaBL
    {
        [Dependency]
        public IVentaRepositor VentaRepository { get; set; }

        [Dependency]
        public IDetalleVentaRepository DetVentaRepository { get; set; }

        [Dependency]
        public IProductoRepository ProductoRepository { get; set; }

        public List<VENTA> GetAllFromVentasByCriterio(string criterio)
        {
            return VentaRepository.GetFromVentasByCriterio(criterio);
        }

        public VENTA GetFromVentaById(int id)
        {
            return VentaRepository.GetFromVentaById(id);
        }

        public void AddVenta(VENTA venta)
        {
            var msg = "";
            var ok = venta.Validate(out msg);
            if (ok)
            {
                ValidarStocks(venta);
                VentaRepository.AddVenta(venta);

                #region UpdateStock
                foreach (var item in venta.DetalleVenta)
                {
                    var actproducto = ProductoRepository.GetFromProductoByID(item.IdProducto);                   
                    actproducto.Stock = actproducto.Stock - item.Cantidad;
                    ProductoRepository.UpdateProducto(actproducto);
                }
                #endregion

            }
            else
            {
                throw new Exception(msg);
            }

        }

        public void UpdateVenta(VENTA venta)
        {            
            var msg = "";
            var ok = venta.Validate(out msg);
            if (ok)
            {
                ValidarStockEditar(venta);

                #region UpdateProductos
                foreach (var item in venta.DetalleVenta)
                {
                    var existeDetal = DetVentaRepository.GetFromProductoByDetalleVentaId(item.IdProducto , venta.Id);
                    if (existeDetal != null)
                    {
                        if (item.Cantidad != existeDetal.Cantidad)
                        {
                            var producto = ProductoRepository.GetFromProductoByID(item.IdProducto);                   
                            producto.Stock = producto.Stock + existeDetal.Cantidad - item.Cantidad;
                            ProductoRepository.UpdateProducto(producto);
                        }
                    }
                    else
                    {
                        var producto = ProductoRepository.GetFromProductoByID(item.IdProducto);     
                        producto.Stock = producto.Stock - item.Cantidad;
                        ProductoRepository.UpdateProducto(producto);
                    }
                }
                #endregion
                VentaRepository.UpdateVenta(venta);
            }
            else
            {
                throw new Exception(msg);
            }

        }

        public void CancelarVenta(int id)
        {
            VentaRepository.CancelarVenta(id);
        }

        private void ValidarStocks(VENTA venta)
        {
            foreach (var item in venta.DetalleVenta)
            {
                var producto = ProductoRepository.GetFromProductoByID(item.IdProducto);     
                var cantActualDetalle = DetVentaRepository.GetFromProductoByDetalleVentaId(item.IdProducto, venta.Id);

                if (cantActualDetalle == null)
                {
                    if (item.Cantidad > producto.Stock)
                    {
                        throw new Exception(string.Format("No hay Stock suficiente para el producto {0}," +
                                          " solo quedan {1} Und.", producto.Descripcion, producto.Stock));
                    }
                }
                if (cantActualDetalle != null)
                {
                    var stockActual = producto.Stock + cantActualDetalle.Cantidad;
                    if (item.Cantidad > stockActual)
                    {
                        throw new Exception(string.Format("La maxima cantidad a elegir del producto {0}," +
                                          " es {1} Und.", producto.Descripcion, stockActual));
                    }
                }
            }
        }

        private void ValidarStockEditar(VENTA venta)
        {
            foreach (var item in venta.DetalleVenta)
            {
                var producto = ProductoRepository.GetFromProductoByID(item.IdProducto);
                var cantActualDetalle = DetVentaRepository.GetFromProductoByDetalleVentaId(item.IdProducto, venta.Id);

                if (cantActualDetalle == null)
                {
                    if (item.Cantidad > producto.Stock)
                    {
                        throw new Exception(string.Format("No hay Stock suficiente para el producto {0}," +
                                          " solo quedan {1} Und.", producto.Descripcion, producto.Stock));
                    }
                }
                if (cantActualDetalle != null)
                {
                    var stockActual = producto.Stock + cantActualDetalle.Cantidad;
                    if (item.Cantidad > stockActual)
                    {
                        throw new Exception(string.Format("La maxima cantidad a elegir del producto {0}," +
                                          " es {1} Und.", producto.Descripcion, stockActual));
                    }
                }
            }
        }


        public List<VENTA> GetFromVentasbyFechasAndCliente(DateTime? fec1, DateTime? fec2, string cliente)
        {
            return VentaRepository.GetFromVentasbyFechasAndCliente(fec1, fec2, cliente);
        }
    }
}
